/**
 * author      : dormi330
 * date        : 2018/7/6
 * project     : mybatis
 * description : TODO
 */

package com.deep.trade.application.order;

import com.deep.trade.adaptor.required.IdService;
import com.deep.trade.common.TradeException;
import com.deep.trade.domain.order.*;
import com.deep.trade.infrastructure.utils.CommonUtils;
import com.deep.trade.order.InDtoEachParcel;
import com.deep.trade.order.ParcelItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AddParcelService {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private OrderQueryRepository orderQueryRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private IdService idService;

    /**
     * 添加包裹
     *
     * @param inDtoEachParcelList
     */
    @Transactional
    public void addParcel(List<InDtoEachParcel> inDtoEachParcelList) throws TradeException {
        logger.info("{}, inDtoEachParcelList={}", CommonUtils.currentClassAndMethod(), inDtoEachParcelList);

        if (null == inDtoEachParcelList && inDtoEachParcelList.size() == 0)
            throw new TradeException("parcel null or empty");

        // cache
        Map<String, TradeOrder> tradeOrderCache = new HashMap<>();
        Map<String, TradeOrderSku> tradeOrderSkuCache = new HashMap<>();
        List<String> cacheOfTradeOrderId = new ArrayList<>();

        for (InDtoEachParcel inDtoEachParcel : inDtoEachParcelList) {
            String tenantCode = inDtoEachParcel.getTenantCode();
            if (null == tenantCode) throw new TradeException("tenantCode cannot be null");

            String token = inDtoEachParcel.getToken();
            if (null == token) throw new TradeException("token cannot be null");

            String tradeOrderId = inDtoEachParcel.getTradeOrderId();
            if (null == tradeOrderId) throw new TradeException("tradeOrderId cannot be null");

            TradeOrder tradeOrder = tradeOrderCache.get(tradeOrderId);
            if (null == tradeOrder) {
                tradeOrder = orderQueryRepository.tradeOrderOfId(tenantCode, tradeOrderId);
                if (null == tradeOrder) throw new TradeException("tradeOrder not exists");

                tradeOrderCache.put(tradeOrderId, tradeOrder);
            }

            // new entity
            OrderParcel orderParcel = new OrderParcel();
            // TODO createdBy updatedBy
            orderParcel.initStartStatus();
            orderParcel.setId(idService.uuid());
            orderParcel.setTradeOrderId(tradeOrderId);
            orderParcel.setTenantCode(tenantCode);
            orderParcel.setTrackingNo(inDtoEachParcel.getTrackingNo());
            orderParcel.setTrackingNoImg(inDtoEachParcel.getTrackingNoImg());
            orderParcel.setLogisticsCompanyCode(inDtoEachParcel.getLogisticsCompanyCode());
            orderParcel.setLogisticsCompanyName(inDtoEachParcel.getLogisticsCompanyName());

            // 获取cache
            if (cacheOfTradeOrderId.indexOf(tradeOrderId) == -1) {
                List<TradeOrderSku> tradeOrderSkuList = orderQueryRepository.orderSkuOfTradeOrder(tenantCode, tradeOrderId);
                cacheOfTradeOrderId.add(tradeOrderId);
                tradeOrderSkuList.stream().forEach(tradeOrderSku -> {
                    tradeOrderSkuCache.put(tradeOrderSku.getId(), tradeOrderSku);
                });
            }

            // entiy 字段填充
            List<ParcelItem> parcelItemList = inDtoEachParcel.getParcelItemList();
            for (ParcelItem parcelItem : parcelItemList) {
                TradeOrderSku tradeOrderSku = tradeOrderSkuCache.get(parcelItem.getTradeOrderSkuId());
                if (null == tradeOrderSku) throw new TradeException("TradeOrderSku not found");
                orderParcel.addParcelItem(tradeOrderSku, parcelItem.getQuantity());
            }

            // 存储前处理 -> 存储
            orderParcel.packToString();
            orderRepository.addParcel(orderParcel);
        }
    }
}
